﻿using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using GalaSoft.MvvmLight;
using ComputerEngine;

namespace DaphneControls.ViewModel
{
    /// <summary>
    /// Internal engine settings view model
    /// </summary>
    public class InternalEngineSettingsVM : ViewModelBase
    {
        private EngineSettings _engineSettings;

        /// <summary>
        /// Dictionary of captions for search algorithm types
        /// </summary>
        private Dictionary<eSearchType, string> _searchTypes = new Dictionary<eSearchType,string>() 
        {
            { eSearchType.NegaMax, "NegaMax" },
            { eSearchType.AlphaBeta, "AlphaBeta" },
            { eSearchType.MTDf, "MTDf" },
            { eSearchType.PVS, "PVS" }
        };
        

        /// <summary>
        /// Initializes a new instance of the InternalEngineSettingsVM class.
        /// </summary>
        public InternalEngineSettingsVM(EngineSettings settings)
        {
            _engineSettings = settings;

            PrepareSearchTypeList();
        }

#region Binding Properties

        public List<SearchRec> SearchTypes
        { get; set; }

        public SearchRec SelectedSearch
        {
            get
            {
                return SearchTypes.FirstOrDefault(s => s.SearchType == _engineSettings.SearchType);
            }
            set
            {
                _engineSettings.SearchType = (value as SearchRec).SearchType;
            }
        }

        public string Depth
        {
            get
            {
                return _engineSettings.MaxDepth.ToString();
            }
            set
            {
                int.TryParse(value, out _engineSettings.MaxDepth);
            }
        }

        public string Time
        {
            get
            {
                return _engineSettings.MaxSeconds.ToString();
            }
            set
            {
                int.TryParse(value, out _engineSettings.MaxSeconds);
            }
        }

        public bool UseTT
        {
            get
            {
                return _engineSettings.UseCache;
            }
            set
            {
                _engineSettings.UseCache = value;
            }
        }

        public bool UseEndGame
        {
            get
            {
                return _engineSettings.UseEndGameDB;
            }
            set
            {
                _engineSettings.UseEndGameDB = value;
            }
        }

        public bool UseKillerMoves
        {
            get
            {
                return _engineSettings.UseKillerMoves;
            }
            set
            {
                _engineSettings.UseKillerMoves = value;
            }
        }

        public bool UseHistoryHeuristics
        {
            get
            {
                return _engineSettings.UseHistoryHeuristics;
            }
            set
            {
                _engineSettings.UseHistoryHeuristics = value;
            }
        }

        public bool UsePositionStrategy
        {
            get
            {
                return _engineSettings.UsePositionStrategy;
            }
            set
            {
                _engineSettings.UsePositionStrategy = value;
            }
        }

        public int CacheSizeMB
        {
            get
            {
                return _engineSettings.CacheSizeMB;
            }
            set
            {
                _engineSettings.CacheSizeMB = value;
            }
        }

#endregion

        /// <summary>
        /// Prepares the list of search types
        /// </summary>
        private void PrepareSearchTypeList() 
        {
            SearchTypes = new List<SearchRec>();
            SearchTypes.Add(new SearchRec(eSearchType.NegaMax, true, _searchTypes[eSearchType.NegaMax]));
            SearchTypes.Add(new SearchRec(eSearchType.AlphaBeta, false, _searchTypes[eSearchType.AlphaBeta]));
            SearchTypes.Add(new SearchRec(eSearchType.MTDf, false, _searchTypes[eSearchType.MTDf]));
            SearchTypes.Add(new SearchRec(eSearchType.PVS, false, _searchTypes[eSearchType.PVS]));
        }

        /// <summary>
        /// Search algorithm binding class
        /// </summary>
        public class SearchRec
        {
            public SearchRec(eSearchType type,  bool depth, string title)
            {
                SearchType = type;
                Depth = depth;
                Title = title;
            }

            public eSearchType SearchType
            { get; set; }

            public bool Depth
            { get; set; }

            public string Title
            { get; set; }

            public override string ToString()
            {
                return Title;
            }
        }
    }
}